using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using ProjectEuler.Core.Helpers;

namespace ProjectEuler.Core
{
    public class Problem34 : IProjectEulerProblem
    {
        private const int UPPER_BOUND_GOOD_ENOUGH = 50000;

        protected int SumOfFactorialDigits(int number)
        {
            var digits = number.ToString();
            var sum = 0;
            foreach (var digit in digits)
            {
                var num = int.Parse(digit.ToString());
                sum += (int) MathHelper.Factorial(num);
            }
            return sum;
        }

        protected IEnumerable<int> NumbersEqualToSumOfFactorialOfDigits()
        {
            // remember that 1! and 2! don't count per the problem description
            for (int i = 3; i <= UPPER_BOUND_GOOD_ENOUGH; i++)
            {
                if(i == SumOfFactorialDigits(i))
                {
                    yield return i;
                }
            }
        }

        public int Number
        {
            get { return 34; }
        }

        public string Description
        {
            get { return "Find the sum of all numbers which are equal to the sum of the factorial of their digits."; }
        }

        public string Answer
        {
            get { return NumbersEqualToSumOfFactorialOfDigits().Sum().ToString(); }
        }
    }

    [TestFixture]
    public class Problem34Tests : Problem34
    {
        [Test]
        public void Test_that_145_is_found()
        {
            Assert.AreEqual(145, SumOfFactorialDigits(145));
        }
    }
}